package chooongg.base.widget.titleBar

import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.annotation.DimenRes
import androidx.annotation.DrawableRes
import androidx.annotation.IntDef
import androidx.annotation.StringRes
import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams
import chooongg.base.R
import chooongg.base.annotation.TitleBarDividerStyle
import chooongg.base.annotation.TitleBarDividerSupportStyle
import chooongg.base.annotation.TranslucentStatusBar
import chooongg.base.utils.*
import kotlinx.android.synthetic.main.titlebar_parent.view.*

abstract class AbsTitleBar @JvmOverloads constructor(
    context: Context, private val attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {

    companion object {
        const val ICON_NAVIGATION = 0
        const val ICON_OPERATION = 1
        const val ICON_NEUTRAL = 2
    }

    @IntDef(ICON_NAVIGATION, ICON_OPERATION, ICON_NEUTRAL)
    annotation class IconMold

    private var isInitFinish = false

    private var isKeepStatusBar = false

    private var isAutoColor = true

    init {
        if (layoutParams != null) {
            updateLayoutParams<ViewGroup.LayoutParams> {
                height = ViewGroup.LayoutParams.MATCH_PARENT
                width = ViewGroup.LayoutParams.WRAP_CONTENT
            }
        }
        configAttribute()
        isInitFinish = true
    }

    private fun configAttribute() {
        inflate(context, R.layout.titlebar_parent, this)
        initLayout()
        val tag = resString(R.string.titleBar_keepStatusBar)
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            if (child.tag != tag) {
                removeView(child)
                findViewById<ConstraintLayout>(R.id.title_content).addView(child)
            }
        }
        if (attrs != null) {
            val typedArray = context.obtainStyledAttributes(attrs, R.styleable.AbsTitleBar, 0, 0)
            typedArray.getString(R.styleable.AbsTitleBar_bar_title)
                .apply { if (this != null) title(this) }
            typedArray.getString(R.styleable.AbsTitleBar_bar_subTitle)
                .apply { if (this != null) subTitle(this) }
            typedArray.getBoolean(R.styleable.AbsTitleBar_bar_autoBack, false)
                .apply { if (this) navigationGoBack() }
            isKeepStatusBar =
                typedArray.getBoolean(R.styleable.AbsTitleBar_bar_keepStatusBar, false)
            isAutoColor = typedArray.getBoolean(R.styleable.AbsTitleBar_bar_autoColor, true)
            divider(
                typedArray.getInteger(
                    R.styleable.AbsTitleBar_bar_dividerStyle,
                    if (context.javaClass.isAnnotationPresent(TitleBarDividerStyle::class.java)) {
                        context.javaClass.getAnnotation(TitleBarDividerStyle::class.java)?.value
                            ?: 0
                    } else 0
                ), false
            )
            typedArray.recycle()
        } else {
            if (context.javaClass.isAnnotationPresent(TitleBarDividerStyle::class.java)) {
                divider(context.javaClass.getAnnotation(TitleBarDividerStyle::class.java)!!.value)
            }
            if (background == null) {

                setBackgroundResource(R.color.colorPrimary)
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
            && context.javaClass.getAnnotation(TranslucentStatusBar::class.java)?.isEnable == true
            && !isKeepStatusBar
        ) {
            title_statusBar.layoutParams.height = getStatusBarHeight()
        }
        if (isAutoColor) autoColor()
    }

    abstract fun initLayout()

    abstract fun color(color: Int): AbsTitleBar

    abstract fun setIconPadding(@IconMold mold: Int, @DimenRes resId: Int): AbsTitleBar
    abstract fun setIconPadding(@IconMold mold: Int, dp: Float): AbsTitleBar

    abstract fun title(title: CharSequence?): AbsTitleBar
    abstract fun title(@StringRes resId: Int): AbsTitleBar

    abstract fun getTitle():String

    abstract fun subTitle(subTitle: CharSequence?): AbsTitleBar
    abstract fun subTitle(@StringRes resId: Int): AbsTitleBar

    abstract fun navigationGoBack(): AbsTitleBar
    abstract fun navigationIcon(drawable: Drawable?, listener: (() -> Unit)?): AbsTitleBar
    abstract fun navigationIcon(@DrawableRes resId: Int, listener: (() -> Unit)?): AbsTitleBar
    abstract fun navigationText(text: CharSequence?, listener: (() -> Unit)?): AbsTitleBar
    abstract fun navigationText(@StringRes resId: Int, listener: (() -> Unit)?): AbsTitleBar

    abstract fun operationIcon(drawable: Drawable?, listener: (() -> Unit)?): AbsTitleBar
    abstract fun operationIcon(@DrawableRes resId: Int, listener: (() -> Unit)?): AbsTitleBar
    abstract fun operationText(text: CharSequence?, listener: (() -> Unit)?): AbsTitleBar
    abstract fun operationText(@StringRes resId: Int, listener: (() -> Unit)?): AbsTitleBar

    abstract fun neutralIcon(drawable: Drawable?, listener: (() -> Unit)?): AbsTitleBar
    abstract fun neutralIcon(@DrawableRes resId: Int, listener: (() -> Unit)?): AbsTitleBar
    abstract fun neutralText(text: CharSequence?, listener: (() -> Unit)?): AbsTitleBar
    abstract fun neutralText(@StringRes resId: Int, listener: (() -> Unit)?): AbsTitleBar

    abstract fun getTitleTextView(): AppCompatTextView
    abstract fun getSubtitleTextView(): AppCompatTextView
    abstract fun getNavigationIconView(): AppCompatImageView
    abstract fun getNavigationTextView(): AppCompatTextView
    abstract fun getOperationIconView(): AppCompatImageView
    abstract fun getOperationTextView(): AppCompatTextView
    abstract fun getNeutralIconView(): AppCompatImageView
    abstract fun getNeutralTextView(): AppCompatTextView

    fun getStatusBarView() = title_statusBar
    fun getContentView() = title_content
    fun getDividerLineView() = title_divider

    fun keepStatusBar(value: Boolean) {
        title_statusBar.layoutParams.height = if (value) 0 else getStatusBarHeight()
    }

    fun show(isTransition: Boolean = true) {
        if (isTransition) animate().translationY(0f).alpha(1f)
        else {
            translationY = 0f
            alpha = 1f
        }
    }

    fun hide(isTransition: Boolean = true, isTransparent: Boolean = false) {
        if (isTransition) animate().translationY(height.toFloat())
            .alpha(if (isTransparent) 0f else 1f)
        else {
            translationY = height.toFloat()
            alpha = 0f
        }
    }

    fun divider(@TitleBarDividerStyle.DividerStyle style: Int, isTransition: Boolean = false) =
        apply {
            if (isTransition) {
                when (style) {
                    TitleBarDividerStyle.LINE -> {
                        title_divider.animate().alpha(1f)
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            animate().translationZ(0f)
                        }
                    }
                    TitleBarDividerStyle.ELEVATION -> {
                        title_divider.animate().alpha(0f)
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            elevation = resDimen(R.dimen.titleBarElevation)
                        } else if (context.javaClass.isAnnotationPresent(TitleBarDividerSupportStyle::class.java)) {
                            val supportStyle =
                                context.javaClass.getAnnotation(TitleBarDividerSupportStyle::class.java)!!.value
                            if (supportStyle != TitleBarDividerStyle.ELEVATION) {
                                when (supportStyle) {
                                    TitleBarDividerStyle.NONE -> title_divider.animate().alpha(0f)
                                    TitleBarDividerStyle.LINE -> title_divider.animate().alpha(1f)
                                }
                            }
                        }
                    }
                    else -> {
                        title_divider.animate().alpha(0f)
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            elevation = 0f
                        }
                    }
                }
            } else {
                when (style) {
                    TitleBarDividerStyle.LINE -> {
                        title_divider.alpha = 1f
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            translationZ = 0f
                        }
                    }
                    TitleBarDividerStyle.ELEVATION -> {
                        title_divider.alpha = 0f
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            elevation = resDimen(R.dimen.titleBarElevation)
                        } else if (context.javaClass.isAnnotationPresent(TitleBarDividerSupportStyle::class.java)) {
                            val supportStyle =
                                context.javaClass.getAnnotation(TitleBarDividerSupportStyle::class.java)!!.value
                            if (supportStyle != TitleBarDividerStyle.ELEVATION) {
                                when (supportStyle) {
                                    TitleBarDividerStyle.NONE -> title_divider.alpha = 0f
                                    TitleBarDividerStyle.LINE -> title_divider.alpha = 1f
                                }
                            }
                        }
                    }
                    else -> {
                        title_divider.alpha = 0f
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            elevation = 0f
                        }
                    }
                }
            }
        }

    fun progress(progress: Int) {
        when (progress) {
            in 1..99 -> {
                title_progress.animate().cancel()
                title_progress.visible()
                title_progress.animate().alpha(1f)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    title_progress.setProgress(progress, true)
                } else title_progress.progress = progress
            }
            else -> {
                title_progress.animate().cancel()
                title_progress.animate().alpha(0f).withEndAction {
                    title_progress.gone()
                }
            }
        }
    }

    override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
        if (isInitFinish && child?.tag != resString(R.string.titleBar_keepStatusBar)) findViewById<ConstraintLayout>(
            R.id.title_content
        ).addView(child, index, params) else super.addView(child, index, params)
    }

    internal fun autoColor() {
        if (background is ColorDrawable) {
            if (ColorUtils.isColorDark((background as ColorDrawable).color)) {
                color(Color.WHITE)
                if (context is Activity) (context as Activity).setStatusBarLightMode(false)
            } else {
                color(resColor(R.color.textVital))
                if (context is Activity) (context as Activity).setStatusBarLightMode(true)
            }
        } else if (context is Activity) (context as Activity).setStatusBarLightMode(false)
    }

    override fun setBackground(background: Drawable?) {
        super.setBackground(background)
        if (isAutoColor) autoColor()
    }
}